﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using Glue;
using Glue.Internals.PrintTool;
using Xunit;

namespace GlueTests.PrintToolTests
{
    public class When_printing_properties
    {
        private readonly Mapping<DomainPerson, GuiPerson> mapping;
        private readonly PrintTool<DomainPerson, GuiPerson> printtool;
        

        public class DomainPerson
        {
            public String Name { get; set; }
            public DomainAddress Address { get; set; }
        }
        public class GuiPerson
        {
            public String Name { get; set; }
            public String City { get; set; }
            public GuiAddress Address { get; set; }
            public String WorkPhone { get; set; }
        }

        public class DomainAddress
        {
            public String City { get; set; }
            public DomainPhones Phones { get; set; }
        }

        public class DomainPhones
        {
            public String Home { get; set; }
            public String Work { get; set; }
        }

        public class GuiAddress
        {
            public String City { get; set; }
        }

        public When_printing_properties()
        {
            mapping = new Mapping<DomainPerson, GuiPerson>();
            printtool = new PrintTool<DomainPerson, GuiPerson>(mapping);
        }

        [Fact]
        public void Should_find_primitive_relation()
        {
            mapping.Relate(x => x.Name, y => y.Name);
            
            var report = printtool.GetReport();

            var lines = new List<ReportLine>(report.GetLines());
            Assert.Equal(1, lines.Count);
            Assert.Equal("Name", lines[0].LeftSidePropertyName);
            Assert.Equal("Name", lines[0].RightSidePropertyName);

            printtool.Print(report, x => Debug.WriteLine(x));
        }

        [Fact]
        public void Should_find_flattened_relation()
        {
            var flattenedMapping = new Mapping<DomainAddress, GuiPerson>();
            flattenedMapping.Relate(x=>x.City,y=>y.City);
            mapping.Flatten(x=>x.Address,flattenedMapping);

            var report = printtool.GetReport();

            var lines = new List<ReportLine>(report.GetLines());
            Assert.Equal(1,lines.Count);
            Assert.Equal("Address.City",lines[0].LeftSidePropertyName);
            Assert.Equal("City",lines[0].RightSidePropertyName);

            printtool.Print(report, x => Debug.WriteLine(x));
        }

        [Fact]
        public void Should_find_flattened_flattened_relation()
        {
            var flattenedPhones = new Mapping<DomainPhones, GuiPerson>();
            flattenedPhones.Relate(x=>x.Work,y=>y.WorkPhone);
            var flattenedAddress = new Mapping<DomainAddress, GuiPerson>();
            flattenedAddress.Flatten(x => x.Phones,flattenedPhones);
            mapping.Flatten(x=>x.Address,flattenedAddress);

            var report = printtool.GetReport();

            var lines = new List<ReportLine>(report.GetLines());
            Assert.Equal(1, lines.Count);
            Assert.Equal("Address.Phones.Work", lines[0].LeftSidePropertyName);
            Assert.Equal("WorkPhone", lines[0].RightSidePropertyName);

            printtool.Print(report, x => Debug.WriteLine(x));
        }

        [Fact]
        public void Should_find_nested_relation()
        {
            var nestedMapping = new Mapping<DomainAddress, GuiAddress>();
            nestedMapping.Relate(x=>x.City,y=>y.City);
            mapping.Relate(x=>x.Address,y=>y.Address,nestedMapping);

            var report = printtool.GetReport();

            var lines = new List<ReportLine>(report.GetLines());
            Assert.Equal(1,lines.Count);
            Assert.Equal("Address.City",lines[0].LeftSidePropertyName);
            Assert.Equal("Address.City", lines[0].RightSidePropertyName);
            
            printtool.Print(report, x => Debug.WriteLine(x));
        }
    }
}

